// Copyright (c) Microsoft Corporation. All rights reserved.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Xml;

using Microsoft.TeamFoundation.Migration.Toolkit;
using Microsoft.TeamFoundation.Migration.Toolkit.Linking;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Proxy;

namespace Microsoft.TeamFoundation.Migration.Toolkit.Wit
{
    using MigrationFileAttachmentOperation = SyncActionContainer<IMigrationFileAttachment>;
    using SyncOperation = SyncActionContainer<ILink>;

    /// <summary>
    /// TFS work item update package.
    /// </summary>
    class TfsWorkItemUpdatePackage : IWorkItemUpdatePackage
    {
        private TfsCore m_core;                             // Shared TFS core
        private XmlDocument m_doc;                          // XML document for creating update statements
        private Collection<MigrationRevision> m_revisions;  // List of revisions
        private Collection<MigrationFileAttachmentOperation> m_fileAttachments; // List of file attachment changes
        private Collection<SyncOperation> m_links;          // List of links
        private string m_workItemType;                      // Name of the work item type
        private Watermark m_target;                         // Target work item (existing items only)
        private string m_sourceId;                          // Source work item
        private ClientService m_clientService;              // WIT service

        
        /// <summary>
        /// Creates a change list for creating a work item of the given type.
        /// </summary>
        /// <param name="core">Shared TFS core</param>
        /// <param name="doc">Document for creating XML elements</param>
        /// <param name="workItemType">Type of the work item that should be created</param>
        /// <param name="sourceId">Id of a source work item</param>
        /// <param name="clientService">Client service</param>
        /// <returns>Change list</returns>
        public TfsWorkItemUpdatePackage(
            TfsCore core,
            XmlDocument doc,
            string workItemType,
            string sourceId, 
            ClientService clientService)
        {
            m_core = core;
            m_doc = doc;
            m_revisions = new Collection<MigrationRevision>();
            m_fileAttachments = new Collection<MigrationFileAttachmentOperation>();
            m_links = new Collection<SyncOperation>();
            m_workItemType = workItemType;
            m_sourceId = sourceId;
            m_clientService = clientService;
        }

        /// <summary>
        /// Creates a change list for updating given work item.
        /// </summary>
        /// <param name="core">Shared TFS core</param>
        /// <param name="doc">Document for creating XML elements</param>
        /// <param name="target">Item that should be updated</param>
        /// <param name="workItemType">Type of the work item</param>
        /// <param name="sourceId">Id of a source work item</param>
        /// <param name="clientService">Client service</param>
        /// <returns>Change list</returns>
        public TfsWorkItemUpdatePackage(
            TfsCore core,
            XmlDocument doc,
            TfsMigrationWorkItem target,
            string sourceId,
            ClientService clientService)
            : this(core, doc, target.WorkItemType, sourceId, clientService)
        {
            m_target = target.Watermark;
        }

        /// <summary>
        /// Returns shared TFS core.
        /// </summary>
        public TfsCore Core { get { return m_core; } }

        /// <summary>
        /// Tfs work item tracking service.
        /// </summary>
        public ClientService ClientService { get { return m_clientService; } }

        /// <summary>
        /// Gets explicitly defined revisions.
        /// </summary>
        public Collection<MigrationRevision> Revisions { get { return m_revisions; } }

        /// <summary>
        /// Gets explicitly defined file attachments changes.
        /// </summary>
        public Collection<MigrationFileAttachmentOperation> FileAttachmentOperations { get { return m_fileAttachments; } }

        /// <summary>
        /// Gets explicitly define link changes
        /// </summary>
        public Collection<SyncOperation> LinkOperations { get { return m_links; } }

        /// <summary>
        /// Returns shared XML document used for creating elements of the update package.
        /// </summary>
        public XmlDocument Document { get { return m_doc; } }

        /// <summary>
        /// Returns name of the work item type.
        /// </summary>
        public string WorkItemType { get { return m_workItemType; } }

        /// <summary>
        /// Returns target work item.
        /// </summary>
        public Watermark Target { get { return m_target; } }

        /// <summary>
        /// Returns source work item id.
        /// </summary>
        public string SourceId { get { return m_sourceId; } }

        /// <summary>
        /// Translates content of the change list into the set of atomic changes.
        /// </summary>
        /// <returns>Set of update statements</returns>
        public IEnumerable<IWorkItemUpdate> Translate()
        {
            return new TfsChangeListTranslator(this);
        }
    }
}
